#!/usr/bin/perl
$DIRECTORY = "/var/log";
$FILENAME_BASE = "secure";
$FAILED_COMMAND = "Failed password";
$WHITELIST = "/var/log/whitelist";
$BLACKLIST = "/etc/hosts.deny";
$APPEND = 0;
$DEBUG = 1;
$VIEW = 1;

#************************************************
#
# Passed:	IN -> Nothing
#		RETURNED -> Array of All IP's with
#				failed authentication
#
# Function: To get parse through a given file
# 		and get any IP's with failed authentication
#		attempts.
#
#************************************************

sub logfile_Input
{
    my @temp_Array = ();
    
    opendir(DIR,$DIRECTORY) || die "No Such Directory: $DIRECTORY";
    

##################################################################
#
#   Reads through any file that contains $FILENAME_BASE 
#
#   What the hell were you thinking!? Good thing you setup logrotate
#
##################################################################

    foreach $file ( sort readdir(DIR) ) 
    {
	if($file =~ /$FILENAME_BASE/i)
	{
	    push(@files, "$DIRECTORY/$file\n");
	}
	    }
    closedir(DIR);

##################################################################
#
#   Tail the log file you dumbass, while(1=1) etc.
# 	
#	While(1=1)
#	{
#	 TAIL-DATA() 
#	
#	 if($line =~ $RANDOM_DATA)
#	 {
#	  then do xyz
#	 }   
#	 
#	 sleep(1)
#	};
#
#
##################################################################

    
    $number_Files = scalar @files;
    $index_Files = $number_Files - 1;
    
    for $index (0 .. $index_Files)
    {
	open(LOG,@files[$index]) or die "Unable to open logfile:$!\n";

	foreach $line (<LOG>)
	{
	    if($line =~ /$FAILED_COMMAND/)
	    {
		while($line =~ /(\d+\.\d+\.\d+\.\d+)/g)
		{
		    push(@temp_Array,"$1\n");
		    #if($1 =~ /69.58.13.42/)
		    #{	
		    #print "testing";
		    #}
		}
		
		while($line =~ /(\d+:\d+:\d+)/g)
		{
		    #push(@temp_Array,"$1\n");
		    #print "$1 ";
		}
		
	    }
	}
    }
    close(LOG);
    return @temp_Array;
}

#************************************************
#
# Passed:	IN -> A single letter 'W/w' or 'B/b'
#			for whitelist or blacklist
#		RETURNED -> Based on the 'W/w' or 'B/b'
#				returns the whitelist IP's
#				for 'W/w' or blacklist IP's
#				for 'B/b'
#				
# Function: To get a list of IP's from the whitelist
# 		or blacklist
#		
#************************************************

sub list_Input
{
    $list = $_[0];
    my @temp_Array = ();
    
    if(($list =~ /W/) or ($list =~ /w/))
    {
	$OPENLIST = $WHITELIST;
    }
    else
    {
	$OPENLIST = $BLACKLIST;
    }
    
    open(OPENLIST) or die("Could not open $OPENLIST.");
    foreach $line (<OPENLIST>)
    {
	if($line =~ /(\d+\.\d+\.\d+\.\d+)/g)
	{
	    push(@temp_Array,"$1\n");
	}
    }
    close(OPENLIST);
    return @temp_Array;
}

#************************************************
#
# Passed:	IN -> An array of IP's
#		RETURNED -> Nothing
#				
# Function: To output a given set of IP's to the blacklist
#		specified in $BLACKLIST above 		
#
#************************************************

sub blacklist_Output
{
    my @temp_Array = ();
    @temp_Array = @_;
    
    if ($APPEND)
    {
	open(OUTPUT, ">$BLACKLIST"); #open for write, overwrite
    }
    else
    {
	open(OUTPUT, ">>$BLACKLIST"); #open for write, append
    }
    
    foreach $temp_IP (@temp_Array)
    {
	print OUTPUT "ALL: $temp_IP";
    }
    
    close(OUTPUT);
}

#************************************************
#
# Passed:	IN -> A single Array that has multiple
#			entries of a single IP
#		RETURNED -> An array that has had each
#				instance of multiple IP's
#				condensed down to a single
#				instance of each IP
#
# Function: To condense a list of mutliple instances
# 		of the same IP into a manageable list
#		with one record of each IP
#
#************************************************

sub trim_IP
{
    my @temp_Array = ();
    @array_Data = @_;
    
    foreach $temp_IP (@array_Data)
    {
	$flag = 0;
	
	for $index (0 .. $count)
	{
	    if($temp_IP eq @temp_Array[$index])
	    {
		$flag = 1;
	    }
	    else
	    {
		
		if(($index == $count) and ($flag == 0))
		{
		    push(@temp_Array,$temp_IP);
		    $count = scalar @temp_Array;	 
		}
	    }
	}
    }
    return @temp_Array;
}

#************************************************
#
# Passed:	IN -> Two variables, consisting of a
#			single character either 'W/w' or
#			'B/b' to represent the blacklist
#			or whitelist. And an array to filter
#			out the list chosen(black/white) from.
#
#		RETURNED -> A array with either the blacklist
#				IP's filtered out, or the
#				whitelist IP's filtered out.
#				
# Function: To provide a list of IP's that are new
# 		and aren't on my whitelist, or blacklist	
#
#************************************************

sub list_IP
{
    my @temp_Array = ();
    my @array_Data = ();
    my @new_Array = ();
    my ($list,@array_Data) = @_;
    
    if(($list =~ /W/) or ($list =~ /w/))
    {
	@temp_Array = &list_Input('W');
    }
    else
    {
	@temp_Array = list_Input('B');
    }
    
    $count = scalar @temp_Array;
    

    foreach $temp_IP (@array_Data)
    {
	$flag = 0;
	for $index (0 .. $count)
	{
	    if($temp_IP eq @temp_Array[$index])
	    {
		$flag = 1;
	    }
	    else
	    {
		if(($index == $count) and ($flag == 0))
		{
		    push(@new_Array,$temp_IP);
		}
	    }
	}
    }
    
    return @new_Array;
}

#************************************************
#
# Passed:	IN -> A single array of IP's condensed down
#		RETURNED -> A array of attempt numbers
#				to coincide with the index
#				of the IP's passed in.
#
# Function: It brings in a list of IP's. Then it checks
# 		each IP, against the main list of uncondensed
#		IP's and counts the number of time each IP
#		is listed. It then stores that number at the
#		same index as the IP it goes with. For instance
#		the IP at array[3] is checked against the main
#		array, and is counted 15 times. It then stores
#		the number 15 in counts[3]. So that the IP at
#		array[x] and the number of attempts at count[x]
#		go togethor.
#
#************************************************

sub count_Attempts
{
    my @temp_Attempts = ();

    my @temp_Array = ();
    my @temp_Array = @_;

    my @temp_Same = ();
    @temp_Same = &trim_IP(@temp_Array);

    $count = 0;
    foreach $IP (@temp_Same)
    {
	my @temp = ();
	$temp_Scalar = 0;
	
	foreach $line (@temp_Array)
	{
	    if($line eq $IP)
 	    {
		if($IP =~ /123./)
		{
		    #print "IP: $IP LINE: $line";
		}
	
		push(@temp, $line);

	    }
	}
	$temp_Scalar = scalar @temp;
	@temp_Attempts[$count] = $temp_Scalar;
	$count += 1;
    }

    return @temp_Attempts;
}

#************************************************
#
# Passed:	IN -> A array of data that you need to do
#			something with
#
#		RETURNED -> Nothing				
#
# Function: This is essentially the function that actually
# 		uses the data you've manipulated.
#
#************************************************
#USEDATA BELOW

sub use_Data
{
 my @temp_Array = ();
 @temp_Array = @_;
 
 $scalar = scalar @temp_Array;
 
 if($scalar > 0)
 {
  chop(@temp_Array);
  if($VIEW == 1)
  {
      print "\n\n     BANNED\n";
      print "________________\n\n";
  }
   
  foreach $temp_IP (@temp_Array)
  {
      if($VIEW == 1)
      {
	  print "BANNED from $FILENAME_BASE: $temp_IP\n";
      }
      
      #system("/usr/local/sbin/ipdrop $temp_IP on");
      
      if($VIEW == 1)
      {
	  print "\n";
      }
  }
 }

#for $index (0 .. $index_Same)#
#{
 #if(@attempts[$index] >= 3)
 #{
  
  #chop(@same[$index]);
  #print "Attempts: @attempts[$index]   IP: @same[$index]";
  #system("/usr/local/sbin/ipdrop @same[$index] on");
  #print "NSLOOKUP for @same[$index]\n\n";  
  #system("nslookup @same[$index]\n");
  #print "___________________________________________________________\n\n\n";
 #}
#}
}

@ip = &logfile_Input;
@same_IP = &trim_IP(@ip);
@whitelist_IP = &list_Input('W');
@blacklist_IP = &list_Input('B');
@white_IP = &list_IP('W', @same_IP);
@black_IP = &list_IP('B', @white_IP);
&blacklist_Output(@black_IP);
&use_Data(@black_IP);

if($DEBUG == 1)
{
    print "\n\n\n___________________\n";
    print "Whitelist:\n";
    print " @whitelist_IP";
    print "___________________\n\n";
    
    print "___________________\n";
    print "Blacklist:\n";
    print " @blacklist_IP";
    print "___________________\n\n";
    
    print "___________________\n";
    print "All IP's:\n";
    print " @same_IP";
    print "___________________\n\n";
    
    @attempts = &count_Attempts(@ip);
    $index_Scalar = scalar @attempts;
    $index_Scalar = $index_Scalar - 1;
    
    print "___________________\n";
    print "IP Attempts:\n";
    for $index (0 .. $index_Scalar)
    {
	print "Attempts: @attempts[$index] IP: @same_IP[$index]";
    }
    print "___________________\n\n";
    
    print "___________________\n";
    print "Banned IP's:\n";
    print " @white_IP";
    print "___________________\n\n";
    
    print "___________________\n";
    print "New IP's to be banned:\n";
    print " @black_IP";
    print "___________________\n";
}
